package com.reactim.message.controller;

import com.reactim.message.connection.FaultRecoveryService;
import com.reactim.message.connection.FaultRecoveryStats;
import com.reactim.common.response.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * 故障恢复控制器
 * 提供故障恢复服务的监控和管理接口
 */
@RestController
@RequestMapping("/api/fault-recovery")
@RequiredArgsConstructor
@Slf4j
public class FaultRecoveryController {

    private final FaultRecoveryService faultRecoveryService;

    /**
     * 获取故障恢复状态
     *
     * @return 故障恢复状态信息
     */
    @GetMapping("/status")
    public Result<Map<String, Object>> getStatus() {
        try {
            FaultRecoveryStats stats = faultRecoveryService.getStats();
            
            Map<String, Object> status = Map.of(
                "redisHealthy", stats.isRedisHealthy(),
                "consecutiveFailures", stats.getConsecutiveFailures(),
                "lastHealthCheckTime", stats.getLastHealthCheckTime(),
                "failoverConnectionCount", stats.getFailoverConnectionCount(),
                "failoverOnlineUserCount", stats.getFailoverOnlineUserCount(),
                "healthStatus", stats.isRedisHealthy() ? "HEALTHY" : "UNHEALTHY"
            );
            
            return Result.success(status);
            
        } catch (Exception e) {
            log.error("获取故障恢复状态失败", e);
            return Result.error("获取故障恢复状态失败: " + e.getMessage());
        }
    }

    /**
     * 手动触发健康检查
     *
     * @return 健康检查结果
     */
    @PostMapping("/health-check")
    public Mono<Result<String>> triggerHealthCheck() {
        log.info("手动触发Redis健康检查");
        
        return faultRecoveryService.manualHealthCheck()
                .map(healthy -> {
                    if (healthy) {
                        return Result.success("健康检查完成，Redis状态正常");
                    } else {
                        return Result.success("健康检查完成，Redis状态异常");
                    }
                })
                .onErrorResume(error -> {
                    log.error("手动健康检查失败", error);
                    return Mono.just(Result.error("健康检查失败: " + error.getMessage()));
                });
    }

    /**
     * 手动触发数据恢复
     *
     * @return 数据恢复结果
     */
    @PostMapping("/recovery")
    public Mono<Result<String>> triggerRecovery() {
        log.info("手动触发数据恢复");
        
        return faultRecoveryService.manualRecovery()
                .map(success -> {
                    if (success) {
                        return Result.success("数据恢复完成");
                    } else {
                        return Result.success("数据恢复失败，Redis可能不健康");
                    }
                })
                .onErrorResume(error -> {
                    log.error("手动数据恢复失败", error);
                    return Mono.just(Result.error("数据恢复失败: " + error.getMessage()));
                });
    }

    /**
     * 重置故障恢复统计信息
     *
     * @return 重置结果
     */
    @PostMapping("/reset-stats")
    public Result<String> resetStats() {
        try {
            log.info("重置故障恢复统计信息");
            faultRecoveryService.resetStats();
            return Result.success("故障恢复统计信息已重置");
            
        } catch (Exception e) {
            log.error("重置故障恢复统计信息失败", e);
            return Result.error("重置故障恢复统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取详细的故障恢复统计信息
     *
     * @return 详细统计信息
     */
    @GetMapping("/stats")
    public Result<FaultRecoveryStats> getDetailedStats() {
        try {
            FaultRecoveryStats stats = faultRecoveryService.getStats();
            return Result.success(stats);
            
        } catch (Exception e) {
            log.error("获取故障恢复详细统计失败", e);
            return Result.error("获取故障恢复详细统计失败: " + e.getMessage());
        }
    }
}